package com.ai.aicodemather.core.saver;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.ai.aicodemather.constant.AppConstant;
import com.ai.aicodemather.exception.ErrorCode;
import com.ai.aicodemather.exception.ThrowUtils;
import com.ai.aicodemather.model.enums.CodeGenTypeEnum;

import java.io.File;
import java.nio.charset.StandardCharsets;

/**
 * 代码文件保存模板 -- 模版方法
 * 模版定义代码文件保存的的基础逻辑，子类只需要实现具体保存逻辑
 */
public abstract class CodeFileSaverTemplate<T> {

    // 文件保存根目录
    private static final String ROOT_PATH = AppConstant.CODE_OUTPUT_ROOT_DIR;

    public final File saveCodeFile(T result, Long appId) {
        // 参数校验
        validateInput(result);
        // 拼接唯一路径
        String filePath = getUniqueFilePath(appId);
        // 保存文件
        saveFiles(filePath, result);
        // 返回文件
        return new File(filePath);
    }


    /**
     * 创建文件的唯一路径,这个路径下存放代码
     *
     * @param appId
     * @return
     */
    private String getUniqueFilePath(Long appId) {
        // 获取代码生成类型，模版为抽象方法，只定义行为，具体实现不管
        String codeType = getCodeGenType().getValue();
        String filePath = String.format("%s_%s", codeType, appId);
        String dirPath = ROOT_PATH + File.separator + filePath;
        FileUtil.mkdir(dirPath);
        return dirPath;
    }

    /**
     * 保存单个文件的方法
     *
     * @param dirPath
     * @param fileName
     * @param content
     */
    public static void saveSingleFile(String dirPath, String fileName, String content) {
        if (StrUtil.isNotBlank(content)) {
            String filePath = dirPath + "/" + fileName;
            FileUtil.writeString(content, filePath, StandardCharsets.UTF_8);
        }
    }


    /**
     * 参数校验 -- 可由子类覆盖
     *
     * @param result
     */
    protected void validateInput(T result) {
        ThrowUtils.throwIf(result == null, ErrorCode.PARAMS_ERROR, "代码为空");
    }

    /**
     * 获取代码生成类型 --子类实现
     *
     * @return
     */
    protected abstract CodeGenTypeEnum getCodeGenType();

    /**
     * 文件保存逻辑 --子类实现
     *
     * @param filePath
     * @param result
     */
    protected abstract void saveFiles(String filePath, T result);
}
